#! /usr/bin/python3
import os.path
import sys
import shlex
import re

from headerutils import *

def pretty_name (name):
  return name.replace(".","_").replace("-","_").replace("/","_").replace("+","_");


include_files = list()
edges = 0
one_c = False
clink = list()
noterm = False

def build_inclist (output, filen):
  global edges
  global one_c
  global clink
  global noterm
  inc = build_include_list (filen)
  if one_c and filen[-2:] == ".c":
    pn = "all_c"
  else:
    pn = pretty_name(filen)
  for nm in inc:
    if pn == "all_c":
      if nm not in clink:
        if len(build_include_list(nm)) != 0 or not noterm:
          output.write (pretty_name(nm) + " -> " + pn + ";\n")
          edges = edges + 1
          if nm not in include_files:
            include_files.append(nm)
        clink.append (nm)
    else:
      output.write (pretty_name(nm) + " -> " + pn + ";\n")
      edges = edges + 1
      if nm not in include_files:
        include_files.append(nm)
  return len(inc) == 0

dotname = "graph.dot"
graphname = "graph.png"

def build_dot_file (file_list):
  global one_c
  output = open(dotname, "w")
  output.write ("digraph incweb {\n");
  if one_c:
    output.write ("all_c [shape=box];\n");
  for x in file_list:
    if x[-2:] == ".h":
      include_files.append (x)
    elif os.path.exists (x):
      build_inclist (output, x)
      if not one_c:
        output.write (pretty_name (x) + "[shape=box];\n")

  for x in include_files:
    term = build_inclist (output, x)
    if term:
      output.write (pretty_name(x) + " [style=filled];\n")

  output.write ("}\n");


files = list()
dohelp = False
edge_thresh = 0
for arg in sys.argv[1:]:
  if arg[0:2] == "-o":
    dotname = arg[2:]+".dot"
    graphname = arg[2:]+".png"
  elif arg[0:2] == "-h":
    dohelp = True
  elif arg[0:2] == "-a":
    one_c = True
    if arg[0:3] == "-at":
      noterm = True
  elif arg[0:2] == "-f":
    if not os.path.exists (arg[2:]):
      print ("Option " + arg +" doesn't specify a proper file")
      dohelp = True
    else:
      sfile = open (arg[2:], "r")
      srcdata = sfile.readlines()
      sfile.close()
      for x in srcdata:
        files.append(x.rstrip())
  elif arg[0:2] == "-n":
    edge_thresh = int (arg[2:])
  elif arg[0:1] == "-":
    print ("Unrecognized option " + arg)
    dohelp = True
  else:
    files.append (arg)
    
if len(sys.argv) == 1:
  dohelp = True

if dohelp:
  print ("Generates a graph of the include web for specified files.")
  print ("Usage:  [-finput_file] [-h] [-ooutput] [file1 ... [filen]]")
  print ("  -finput_file : Input file containing a list of files to process.")
  print ("  -ooutput : Specifies output to output.dot and output.png.")
  print ("             defaults to graph.dot and graph.png.")
  print ("  -nnum : Specifies the # of edges beyond which sfdp is invoked. def=0.")
  print ("  -a : Aggregate all .c files to 1 file.  Shows only include web.")
  print ("  -at : Aggregate, but don't include terminal.h to .c links.")
  print ("  -h : Print this help.")
else:
  print (files)
  build_dot_file (files)
  if edges > edge_thresh:
    os.system ("sfdp -Tpng " + dotname + " -o" + graphname)
  else:
    os.system ("dot -Tpng " + dotname + " -o" + graphname)


